<html lang="zh-cn">
<head>
    <meta charset="utf-8"/>
    <title>web-cmd</title>
    <link rel="icon" href="favicon.ico"/>
    <link rel="stylesheet" href="css/cmd.css"/>
    <script type="text/javascript" src="js/jquery.js"></script>
    <script type="text/javascript" src="/socket.io/socket.io.js"></script>
    <script type="text/javascript">
    var socket = io();
    let lineBuffer = '';
    let bScroll = true;
    let history = [];
    let currentCmd = -1;

    function $$(id) {
        return document.getElementById(id);
    }

    function executeCmd(cmd) {
        var d = {
            action: '/executecmd',
            cmd: cmd
        };
        socket.emit('add request', JSON.stringify(d));
    }

    function sayHello() {
        var d = {
            action: '/executecmd',
            cmd: 'hello'
        };
        socket.emit('add request', JSON.stringify(d));
    }

    socket.on('chat message', function (msg) {
        // appendMessage('[INFO]' + msg);
        appendMessage(msg);
    });

    socket.on('error message', function (msg) {
        appendMessage('[ERROR]' + msg);
    });

    function appendMessage(msg) {
        //console.log(msg);
        if (!msg || msg.length == 0) {
            return;
        }
        const changeLine = (msg[msg.length-1]=='\n');
        msg = msg.replace(/\r\n/g, '\n');
        var lines = msg.split('\n');
        if (lineBuffer.length > 0) {
            lines[0] = lineBuffer + lines[0];
            lineBuffer = '';
        }
        if (!changeLine) {
            lineBuffer = lines[lines.length-1];
            lines.splice(lines.length-1, 1);
        }
        let end = false;
        lines.forEach(line => {
            if (end) {
                return;
            }
            if (line.indexOf('\r') >= 0) {
                var tmpblocks = line.split('\r');
                line = tmpblocks[tmpblocks.length-1];
            }
            if (line == '[END]') {
                end = true;
            } else if (line.substring(0, 7) == '[ERROR]') {
                $('#msgcontainer').append($('<div>').addClass('errMsg').html(line));
            } else {
                $('#msgcontainer').append($('<div>').html(line));
            }
            if ($('#msgcontainer')[0].children.length > 2000) {
                $('#msgcontainer')[0].removeChild($('#msgcontainer')[0].children[0]);
            }
        });
        // 显示命令提示符
        $('#msgcontainer').append($('<br>'));
        $('#msgcontainer').append('&gt;&nbsp;');
        $('#msgcontainer').append($('<div style="text-indent: 2em; display: inline;">'));
        // 自动滚屏
        if (bScroll) {
            document.getElementById('msg_end').scrollIntoView();
        }
        // $('msg_end').focus();
    }

    function showMessages() {
        $('#messages')[0].style.display = 'block';
    }

    function clearMessages() {
        $('#messages')[0].style.display = 'none';
    }

    window.onload = function () {
        showMessages();
        sayHello();
    }

    window.onkeydown = function (keyObj) {
        console.log(keyObj);
        let cmdObj = $('#msgcontainer div:last');
        if (keyObj.ctrlKey) {
            if (keyObj.key == 'c') {
                appendMessage('^C');
            }
        } else if (keyObj.key.length == 1) {
            cmdObj.append($('<span>').text(keyObj.key));
        } else if (keyObj.code == 'Backspace') {
            $('#msgcontainer div:last span').last().remove();
        } else if (keyObj.code == 'Enter') {
            const cmdStr = cmdObj.text();
            if (cmdStr.length == 0) {
                return;
            }
            cmdObj.append('<br>');
            history.push(cmdStr);
            executeCmd(cmdStr);
        } else if (keyObj.code == 'ArrowUp') {
            if (history.length == 0) {
                return;
            }
            let newCmd = currentCmd;
            if (currentCmd == -1) {
                newCmd = history.length - 1;
            } else if (currentCmd > 0) {
                newCmd--;
            }
            if (newCmd != currentCmd) {
                showHistory(newCmd);
            }
        } else if (keyObj.code == 'ArrowDown') {
            if (history.length == 0) {
                return;
            }
            let newCmd = currentCmd;
            if (currentCmd == history.length - 1) {
                newCmd = -1;
            } else if (currentCmd != -1) {
                newCmd++;
            }
            if (newCmd != currentCmd) {
                showHistory(newCmd);
            }
        }
    }

    function showHistory(cmdPosition) {
        let cmdStr = '';
        if (cmdPosition >= 0) {
            cmdStr = history[cmdPosition];
        }
        $('#msgcontainer div:last span').remove();
        let cmdObj = $('#msgcontainer div:last');
        for (let i = 0; i < cmdStr.length; i++) {
            cmdObj.append($('<span>').text(cmdStr[i]));
        }
        currentCmd = cmdPosition;
    }
    </script>
</head>
<body>
    <div id='messages'>
        <div class='closebtn'><input type='checkbox' id='autoScroll' checked='checked' onchange='bScroll=this.checked'/><label for='autoScroll'>自动滚屏</label>&nbsp;&nbsp;&nbsp;&nbsp;</div>
        <div id='msgcontainer'></div>
        <div id='msg_end'></div>
    </div>
</body>
</html>
